<?php
/**
 * PaypalController.php
 *
 * @copyright  2022 beikeshop.com - All Rights Reserved
 * @link       https://beikeshop.com
 * @author     Edward Yang <yangjin@guangda.work>
 * @created    2022-08-10 18:57:56
 * @modified   2022-08-10 18:57:56
 *
 * https://www.zongscan.com/demo333/1311.html
 * https://clickysoft.com/how-to-integrate-paypal-payment-gateway-in-laravel/
 * https://www.positronx.io/how-to-integrate-paypal-payment-gateway-in-laravel/
 */

namespace Plugin\Wooshpay\Controllers;

use Beike\Repositories\OrderRepo;
use Beike\Repositories\OrderPaymentRepo;
use Beike\Services\StateMachineService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Plugin\Wooshpay\Services\WooshpayService;

class WooshpayController
{

    /**
     * 创建 Wooshpay Checkout Session
     *
     * 根据 Wooshpay 文档 (https://docs.wooshpay.com/doc-1722914#create-checkout)
     * 创建一个 Checkout Session，这是客户在重定向到支付表单时看到的程序化表示
     *
     * Checkout Session 配置包括：
     * - line_items: 要收费的商品项目
     * - currency: 使用的货币
     * - success_url: 客户完成支付后重定向的页面
     * - cancel_url: 客户点击取消时重定向的页面
     * - mode: 支付模式 (payment)
     * - payment_intent_data: 包含商户订单ID、用户ID、收货信息等
     *
     * 注意：Checkout Sessions 在创建后 24 小时过期
     *
     * @param Request $request 包含订单号的请求数据
     * @return JsonResponse 返回包含 Checkout Session URL 的响应，客户将被重定向到此 URL 完成支付
     * @throws \Throwable
     */
    public function create(Request $request) : JsonResponse
    {
        try {
            // 解析请求数据，获取订单号
            $data        = \json_decode($request->getContent(), true);
            $customer    = current_customer();

            // 根据订单号获取订单信息
            $order      =   OrderRepo::getOrderByNumber($data['orderNumber'] , $customer);

            // 初始化 Wooshpay 服务，传入订单信息用于构建支付参数
            $wooshpayService   =    new WooshpayService($order);

            // 调用 Wooshpay API 创建 Checkout Session
            // 这将返回一个包含支付 URL 的响应，前端将重定向用户到此 URL 完成支付
            return response()->json($wooshpayService->createOrder($data));
        } catch (\Exception $e)
        {
            dd($e);
        }
    }

    /**
     * 简化的支付状态确认方法
     * 主要用于前端弹窗显示，实际支付状态由webhook处理
     *
     * @param Request $request 包含 Checkout Session ID 和订单号的请求
     * @return JsonResponse 返回支付确认结果
     */

//    public function capture(Request $request) :JsonResponse{
//        try {
//            // 解析前端传递的数据，包含 Checkout Session ID 和订单号
//            $data = \json_decode($request->getContent(), true);
//            $customer = current_customer();
//
//            Log::info('支付后续前端调用', [
//                'request_data' => $data,
//                'customer_id' => $customer->id ?? null
//            ]);
//
//            // 根据订单号获取订单信息
//            $order = OrderRepo::getOrderByNumber($data['orderNumber'], $customer);
//
//            if (!$order) {
//                return response()->json(['errCode' => 404, 'message' => trans('Wooshpay::setting.order_not_found')]);
//            }
//
//            // 检查订单状态，避免重复支付处理
//            if ($order->status === StateMachineService::PAID) {
//                Log::info('订单已支付: ' . $order->number);
//                return response()->json(['errCode' => 200, 'message' => trans('Wooshpay::setting.payment_success'), 'data' => ['status' => 'complete']]);
//            }
//
//            // 只处理未支付状态的订单
//            if ($order->status !== StateMachineService::UNPAID) {
//                return response()->json(['errCode' => 400, 'message' => trans('Wooshpay::setting.order_status_invalid')]);
//            }
//
//            // 调用 Wooshpay API 查询 Checkout Session 状态
//            $wooshpayService = new WooshpayService($order);
//            $originalData = $data; // 保存原始数据，用于后续重新查询订单状态
//            $data = $wooshpayService->confirm($data);
//
//            Log::info('确认结果', ['data' => $data, 'order_number' => $order->number]);
//
//            // 检查 Wooshpay API 调用是否成功
//            if (isset($data['errCode']) && $data['errCode'] !== 200) {
//                Log::warning('Wooshpay API错误 confirm', ['data' => $data, 'order_number' => $order->number]);
//
//                // API查询失败时，再次检查订单状态（可能Webhook已更新）
//                // 这是处理竞态条件的重要逻辑：Webhook可能比前端查询更快完成订单状态更新
//                $orderRefresh = OrderRepo::getOrderByNumber($order->number, $customer);
//                if ($orderRefresh->status === StateMachineService::PAID) {
//                    Log::info('API查询失败但订单已通过Webhook支付: ' . $order->number);
//                    return response()->json([
//                        'errCode' => 200,
//                        'message' => trans('Wooshpay::setting.payment_success'),
//                        'data' => ['status' => 'complete']
//                    ]);
//                }
//
//                return response()->json(['errCode' => 400, 'message' => trans('Wooshpay::setting.payment_query_failed'), 'data' => $data]);
//            }
//
//            // 检查支付状态 - 从 Wooshpay Checkout Session 响应中提取多个状态字段
//            // 根据 Wooshpay 文档，需要检查多个状态字段来确保支付真正完成：
//
//            // 1. session.status - Checkout Session 的整体状态
//            //    - 'open': 会话已创建，等待支付
//            //    - 'complete': 会话已完成，支付成功
//            //    - 'expired': 会话已过期（24小时后）
//            $paymentStatus = $data['status'] ?? '';
//
//            // 2. payment_intent.status - PaymentIntent 的详细状态
//            //    - 'requires_payment_method': 需要支付方式
//            //    - 'requires_confirmation': 需要确认
//            //    - 'requires_action': 需要额外操作（如3D验证）
//            //    - 'processing': 正在处理
//            //    - 'succeeded': 支付成功
//            //    - 'canceled': 已取消
//            $paymentIntentStatus = $data['payment_intent']['status'] ?? '';
//
//            // 3. session.payment_status - Checkout Session 的支付状态
//            //    - 'unpaid': 未支付
//            //    - 'paid': 已支付
//            //    - 'no_payment_required': 无需支付（免费订单）
//            $sessionPaymentStatus = $data['payment_status'] ?? '';
//
//            Log::info('支付状态检查', [
//                '会话状态' => $paymentStatus,
//                '付款_意向_状态' => $paymentIntentStatus,
//                '会话_付款_状态' => $sessionPaymentStatus,
//                '订单编号' => $order->number
//            ]);
//
//            try {
//                DB::beginTransaction();
//
//                // 检查多个支付状态字段，确保支付真正完成
//                // 根据 Wooshpay 文档和最佳实践，需要同时满足以下条件才认为支付成功：
//                // 1. session.status === 'complete' - Checkout Session 已完成
//                // 2. payment_intent.status === 'succeeded' OR session.payment_status === 'paid'
//                //    - PaymentIntent 成功 或 会话支付状态为已支付
//                // 这种多重验证可以确保支付真正完成，避免状态不一致的问题
//                $isPaymentComplete = (
//                    $paymentStatus === 'complete' &&
//                    ($paymentIntentStatus === 'succeeded' || $sessionPaymentStatus === 'paid')
//                );
//
//                if ($isPaymentComplete) {
//                    // 更新订单状态为已支付
//                    StateMachineService::getInstance($order)->changeStatus(StateMachineService::PAID);
//                    DB::commit();
//                    Log::info('订单付款状态更新为已付: ' . $order->number);
//
//                    // 返回支付成功响应
//                    return response()->json([
//                        'errCode' => 200,
//                        'message' => trans('Wooshpay::setting.payment_success'),
//                        'data' => ['status' => 'complete']
//                    ]);
//                } else {
//                    // 支付未完成 - 状态检查未通过
//                    DB::rollBack();
//                    Log::info('付款未完成', [
//                        'session_status' => $paymentStatus,
//                        'payment_intent_status' => $paymentIntentStatus,
//                        'session_payment_status' => $sessionPaymentStatus,
//                        'order_number' => $order->number
//                    ]);
//
//                    // 处理竞态条件：再次判断订单是否为已支付
//                    // 可能的情况：Webhook 回调比前端查询更快完成了订单状态更新
//                    // 这种情况下，虽然 API 查询显示支付未完成，但订单实际已通过 Webhook 更新为已支付
//                    $ordera = OrderRepo::getOrderByNumber($originalData['orderNumber'], $customer);
//
//                    if ($ordera->status === StateMachineService::PAID) {
//                        // Webhook 已经处理了支付成功，返回成功状态
//                        return response()->json([
//                            'errCode' => 200,
//                            'message' => trans('Wooshpay::setting.payment_success'),
//                            'data' => ['status' => 'complete']
//                        ]);
//                    }
//
//                    // 支付确实未完成，返回详细的状态信息供调试
//                    return response()->json([
//                        'errCode' => 400,
//                        'message' => trans('Wooshpay::setting.payment_not_completed'),
//                        'data' => [
//                            'status' => $paymentStatus,
//                            'payment_intent_status' => $paymentIntentStatus,
//                            'session_payment_status' => $sessionPaymentStatus
//                        ]
//                    ]);
//                }
//            } catch (\Exception $e) {
//                // 数据库操作异常处理
//                DB::rollBack();
//                Log::error('未能更新订单付款状态', [
//                    'order_number' => $order->number,
//                    'error' => $e->getMessage()
//                ]);
//
//                // 数据库更新失败时的兜底逻辑：再次检查订单状态
//                // 可能的情况：Webhook 已经成功更新了订单状态，但前端的数据库操作失败
//                // 这种情况下应该返回成功，避免用户看到错误信息
//                $orderRefresh = OrderRepo::getOrderByNumber($order->number, $customer);
//                if ($orderRefresh->status === StateMachineService::PAID) {
//                    Log::info('数据库更新失败但订单已通过Webhook支付: ' . $order->number);
//                    return response()->json([
//                        'errCode' => 200,
//                        'message' => trans('Wooshpay::setting.payment_success'),
//                        'data' => ['status' => 'complete']
//                    ]);
//                }
//
//                // 数据库更新确实失败，返回错误
//                return response()->json(['errCode' => 500, 'message' => trans('Wooshpay::setting.payment_status_update_failed')]);
//            }
//
//            // 正常流程结束，返回成功（这行代码理论上不会执行到）
//            return response()->json(['errCode' => 200, 'message' => 'ok', 'data' => $data]);
//
//        } catch (\Exception $e) {
//            // 最外层异常捕获，处理所有未预期的错误
//            Log::error('Wooshpay 捕获错误', [
//                'error' => $e->getMessage(),
//                'trace' => $e->getTraceAsString()
//            ]);
//            return response()->json(['errCode' => 500, 'message' => trans('Wooshpay::setting.payment_failed')]);
//        }
//    }

    /**
     * Wooshpay Webhook处理
     * 接收Wooshpay的支付状态通知
     */
    public function webhook(Request $request): JsonResponse
    {
        Log::info('======Wooshpay Webhook 回调执行 ======');

        try {
            $payload = $request->all();
            Log::info('Wooshpay Webhook 有效载荷', $payload);

            // 验证事件类型
            $eventType = $payload['type'] ?? '';

            $eventData = $payload['data']['object'] ?? [];
            Log::info('Wooshpay Webhook 事件类型: ' . $eventType);

            // 处理支付成功事件
            if ($eventType === 'payment_intent.succeeded') {
                $this->handlePaymentSuccess($eventData);
            } elseif ($eventType === 'payment_intent.payment_failed') {
                $this->handlePaymentFailed($eventData);
            }

            // 返回200状态码确认收到
            return response()->json(['status' => 'success'], 200);

        } catch (\Exception $e) {
            Log::error('Wooshpay Webhook 错误: ' . $e->getMessage(), [
                'exception' => $e,
                'payload' => $request->all()
            ]);

            // 即使出错也返回200，避免Wooshpay重复发送
            return response()->json(['status' => 'error', 'message' => $e->getMessage()], 200);
        }
    }

    /**
     * 处理支付成功
     */
    private function handlePaymentSuccess($paymentIntent)
    {
        $merchantOrderId = $paymentIntent['merchant_order_id'] ?? '';

        if (empty($merchantOrderId)) {
            Log::warning('Wooshpay Webhook: 商家_订单_id为空');
            return;
        }

        Log::info('Processing payment 订单成功,单号: ' . $merchantOrderId);

        // 查找订单
        $order = OrderRepo::getOrderByNumber($merchantOrderId);

        if (!$order) {
            Log::warning('Wooshpay Webhook: 未找到订单: ' . $merchantOrderId);
            return;
        }

        // 检查订单状态，避免重复处理
        if ($order->status === StateMachineService::PAID) {
            Log::info('Wooshpay Webhook: 订单已支付: ' . $merchantOrderId);
            return;
        }

        try {
            DB::beginTransaction();

            // 记录支付信息
            OrderPaymentRepo::createOrUpdatePayment($order->id, [
                'transaction_id' => $paymentIntent['id'] ?? '',
                'callback' => $paymentIntent
            ]);

            // 更新订单状态为已支付
            StateMachineService::getInstance($order)->changeStatus(StateMachineService::PAID);

            DB::commit();

            Log::info('Wooshpay Webhook: 订单付款处理成功: ' . $merchantOrderId);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Wooshpay Webhook: 无法处理订单的付款: ' . $merchantOrderId, [
                'error' => $e->getMessage()
            ]);
            throw $e;
        }
    }

    /**
     * 处理支付失败
     */
    private function handlePaymentFailed($paymentIntent)
    {
        $merchantOrderId = $paymentIntent['merchant_order_id'] ?? '';

        Log::info('订单付款处理失败,单号: ' . $merchantOrderId);

        // 可以在这里添加支付失败的处理逻辑
        // 比如发送邮件通知、记录失败原因等
    }
}
